/**
    @file translate.h
    @brief Translate abstract syntax tree into Tree language
    
    The translate module is a wrapper of tree module and frame module. It
    translate abstract syntax tree into tree language and stores them into its
    own data structure.
*/

#ifndef __TRANSLATE_H__
#define __TRANSLATE_H__
#include "temp.h"
#include "frame.h"
#include "absyn.h"
#include "types.h"

typedef struct Tr_exp_ *Tr_exp;            ///<Translated expression type
typedef struct Tr_access_ *Tr_access;    ///<Translated access type
typedef struct Tr_accessList_ *Tr_accessList;///<Translated access list type
typedef struct Tr_level_ *Tr_level;        ///<Translated level type

///Level is a wrapper of frame and access list
struct Tr_level_
{
    Tr_level parent;
    Tr_accessList accessList;
    F_frame frame;
    unsigned depth;
};

///Create a new access list
Tr_accessList Tr_AccessList(Tr_access data, Tr_accessList next);

///Get the outermost level
Tr_level Tr_outermost();
///Create a new level
Tr_level Tr_newLevel(Tr_level parent, Temp_label name, U_boolList formals);
///Get the depth ot the level
unsigned Tr_getLevelDepth(Tr_level);
///Get the size of a type in byte
unsigned Tr_getSize(Ty_ty type);

///
Tr_accessList Tr_formals(Tr_level level);
///allocate a local variable in a specific level
Tr_access Tr_allocLocal(Tr_level level, bool escape, unsigned size);

///Get all the stm
/**Every time the Tr_appendStm is called, the expression will append to the stm
list, and you can retrieve this list by calling this function.*/
T_stmList Tr_getStmList();
///Append a expression at the tail of the stmlist
void   Tr_appendStm(Tr_exp exp);

///Return a translated expression representing nothing
Tr_exp Tr_nullExp();
///Translate two exp into a sequence exp
Tr_exp Tr_seqExp(Tr_exp data, Tr_exp next);
///Translate a int into a Tr_exp
Tr_exp Tr_intExp(int i);

Tr_exp Tr_varBase(Tr_access a, Tr_level level);   ///<Get the base address of the var
Tr_exp Tr_simpleVar(Tr_access a, Tr_level level);
Tr_exp Tr_subArrayVar(Tr_exp mainArraySub, Tr_exp *vsub, Ty_subList tsub, int singleSize);
Tr_exp Tr_memVar(Tr_exp varAddress); ///<Get the value of a memory address

///Translate a mono-operator expression
Tr_exp Tr_monoOper(int op, Tr_exp exp);
///Translate a operator expression with 2 expression to operate with
Tr_exp Tr_binOper(int op, Tr_exp left, Tr_exp right);
///Translate a condition operator expression
Tr_exp Tr_condOper(int op, Tr_exp left, Tr_exp right);
///Translate a comparation expression
Tr_exp Tr_compare(int op, Tr_exp left, Tr_exp right);

///Translate a if expression
Tr_exp Tr_if(Tr_exp test, Tr_exp then, Tr_exp elsee);
///Translate a break expression
Tr_exp Tr_break(Temp_label lend);
///Translate a while expression
Tr_exp Tr_while(Tr_exp test, Tr_exp body, Temp_label lend);
///Translate a for expression
Tr_exp Tr_for(Tr_exp lo, Tr_exp test, Tr_exp hi, Tr_exp body, Temp_label lend);
///Translate a function call expression
Tr_exp Tr_call(S_table venv, S_table tenv, Temp_label label,
        Tr_level level, A_expList args, Temp_label breakk);
///Translate a assignment expression
Tr_exp Tr_assign(Tr_exp left, Tr_exp right);
///Translate a var declaration expression
Tr_exp Tr_varDec(Tr_access var, Tr_exp init, Tr_level level);
///Translate a functino declaration expression
Tr_exp Tr_funcDec(S_symbol name, Tr_exp body, Tr_level level);
#endif
